#include <iostream>
#include <conio.h>
#define SIZE    50
#define LEVELS 15
using namespace std;

struct objekt{
   int tal;
   struct objekt *left,*right;
};
typedef struct objekt objekt;

template <class Qtype> class MyQueue {
    Qtype queue[SIZE];
    int first, last, size;

    public:

    MyQueue(){
        first = 0; last = 0; size = 0;
    }

    void enQueue(Qtype newElem){
        if(last+1 == first || (last+1 == SIZE && first == 0)){
            cout << "Error, queue is full!" << endl;
            return;}

        last++; size++;
        if(last==SIZE)
            last = 0;
        queue[last] = newElem;
    }

    Qtype deQueue(){
        if(first == last){
            cout << "You tried getting object from empty queue!" << endl;
            //return NULL; <-- replace with throw statement plx
            }

        first++; size--;
        if(first==SIZE)
            first = 0;
        return queue[first];
    }

    void deQueueLast(){
        if(first == last){
            cout << "Erranous call to dequeueLast. Bad boy!" << endl;
            return;
        }

        if(last!=0){
            last--;
            size--;}
    }

    int getSize(){ return size; }
};

objekt *InsertTree(objekt *p,objekt ny){
  objekt *z;

  if(p==NULL){
    z=(objekt *) malloc(sizeof(objekt));
    *z=ny;
    z->left=NULL;
    z->right=NULL;
    return z;
  }
  else
    if(ny.tal<p->tal)
      p->left=InsertTree(p->left,ny);
    else
      p->right=InsertTree(p->right,ny);
    return p;
}

objekt *Init(void){
  objekt p,*start;
  int i,t,n;
  FILE *infil;

  infil=fopen("test.txt","rt");
  fscanf(infil,"%d",&n);
  start=NULL;
  for(i=1;i<=n;i++){
    fscanf(infil,"%d",&t);
    p.tal=t;
    p.right=NULL;
    p.left=NULL;
    start=InsertTree(start,p);
  }
  fclose(infil);
  return start;
}

class qKeeper{
    MyQueue<int> *theQs[LEVELS];

    public:
    qKeeper(){
       for(int i =0; i<LEVELS; i++)
           theQs[i] = new MyQueue<int>();
    }

    ~qKeeper(){
        for(int i =0; i<LEVELS; i++)
            delete theQs[i];
    }

    MyQueue<int> *getQueue(int index){
        return theQs[index];
    }

};

void postorder(objekt *start, int level, qKeeper *qK){
   objekt *x;
   x=start;
   if(x!=NULL){
      postorder(x->left, level+1, qK);
      postorder(x->right, level+1, qK);
      //printf("%d at level %d\n",x->tal, level);
      qK->getQueue(level)->enQueue(x->tal);
   }
}

void PrintTreeLevel(objekt *start){
    qKeeper *qK = new qKeeper();
    postorder(start, 1, qK);

    int level = 0, size;
    do{
        cout << "\n";
        size = qK->getQueue(level)->getSize();
        for(int i = 0; i<size; i++)
            cout << qK->getQueue(level)->deQueue() << " ";
    } while(qK->getQueue(++level)->getSize() != 0);

    delete(qK);
}

int main(void){
   objekt *start;

   start=Init();
   PrintTreeLevel(start);

   getch();
}
